from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ValidationError
from django.db import models


class User(AbstractUser):
    class Role(models.TextChoices):
        STUDENT = "student", "Student"
        TEACHER = "teacher", "Teacher"

    role = models.CharField(
        max_length=20,
        choices=Role.choices,
        default=Role.STUDENT,
    )
    assigned_teacher = models.ForeignKey(
        "self",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="students",
        limit_choices_to={"role": Role.TEACHER},
    )

    def clean(self):
        super().clean()
        if self.assigned_teacher:
            if self.assigned_teacher_id == self.id:
                raise ValidationError(
                    {"assigned_teacher": "A user cannot be their own teacher."}
                )
            if self.assigned_teacher.role != self.Role.TEACHER:
                raise ValidationError(
                    {"assigned_teacher": "Assigned user must have the teacher role."}
                )
        if self.role == self.Role.TEACHER and self.assigned_teacher_id:
            raise ValidationError(
                {"assigned_teacher": "Teachers cannot be assigned another teacher."}
            )

    def save(self, *args, **kwargs):
        self.full_clean()
        return super().save(*args, **kwargs)

    @property
    def is_teacher(self):
        return self.role == self.Role.TEACHER

    @property
    def is_student(self):
        return self.role == self.Role.STUDENT


class UserNotification(models.Model):
    class Category(models.TextChoices):
        ANNOUNCEMENT = "announcement", "Announcement"
        ASSIGNMENT = "assignment", "Assignment"
        MESSAGE = "message", "Message"

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="notifications",
    )
    title = models.CharField(max_length=255)
    message = models.TextField(blank=True)
    link = models.CharField(max_length=255, blank=True)
    category = models.CharField(
        max_length=32,
        choices=Category.choices,
        default=Category.MESSAGE,
    )
    created_at = models.DateTimeField(auto_now_add=True)
    read_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ("-created_at",)
        indexes = [
            models.Index(fields=("user", "read_at")),
        ]

    def __str__(self) -> str:
        return f"{self.title} -> {self.user.username}"

    @property
    def is_unread(self) -> bool:
        return self.read_at is None
